﻿#include <iostream>
#include "ANPRTH.h"
#include "TH_PlateID.h"

TH_PlateIDCfg plateConfigTh;
TH_RECT region;

ANPRTH::ANPRTH()
{
    logger = log4cxx::Logger::getLogger("ANPRTH");

    error = false;
    enableRegion = false;
#ifdef _WIN32
    mutex = CreateMutex(NULL, FALSE, NULL);
#endif
}

ANPRTH::~ANPRTH()
{
    TH_UninitPlateIDSDK(&plateConfigTh);
#ifdef _WIN32
    CloseHandle(mutex);
#endif
}

int ANPRTH::Init(int mode, int minPlateWidth, int maxPlateWidth, int maxImageWidth, int maxImageHeight, RECT *region,
    bool doubleRowYellowLP, bool doubleRowPoliceLP, bool doubleRowArmyLP, bool embassyLP, bool tractorLP, bool airportLP,
    std::string province)
{
    memset(&plateConfigTh, 0, sizeof(plateConfigTh));
    plateConfigTh.nMinPlateWidth = minPlateWidth;
    plateConfigTh.nMaxPlateWidth = maxPlateWidth;
    plateConfigTh.nMaxImageWidth = maxImageWidth;
    plateConfigTh.nMaxImageHeight = maxImageHeight;
    plateConfigTh.bVertCompress = 0;
    plateConfigTh.bIsFieldImage = 0;
    plateConfigTh.bOutputSingleFrame = 1;
    plateConfigTh.bMovingImage = mode;
    plateConfigTh.pFastMemory = mem1;
    plateConfigTh.nFastMemorySize = 0x4000;
    plateConfigTh.pMemory = mem2;
    plateConfigTh.nMemorySize = 100000000;
    plateConfigTh.nImageFormat = ImageFormatBGR;
#ifdef __linux__
    plateConfigTh.bUTF8 = 1;
#endif

    int ret = TH_InitPlateIDSDK(&plateConfigTh);
    if (ret < 0)
    {
        LOG4CXX_ERROR(logger, "TH_InitPlateIDSDK() error: " << ret);

        goto error;
    }

    ret = TH_SetImageFormat(ImageFormatBGR, false, false, &plateConfigTh);
    if (ret < 0) goto error;

    ret = TH_SetRecogThreshold(5, 2, &plateConfigTh);
    if (ret < 0) goto error;

    if (province.size() != 0)
    {
        ret = TH_SetProvinceOrder((char *)province.c_str(), &plateConfigTh);
        if (ret < 0) goto error;
    }

    // 双层黄色车牌
    if (doubleRowYellowLP)
        TH_SetEnabledPlateFormat(PARAM_TWOROWYELLOW_ON, &plateConfigTh);

    // 双层武警车牌
    if (doubleRowPoliceLP)
        TH_SetEnabledPlateFormat(PARAM_ARMPOLICE2_ON, &plateConfigTh);

    // 双层军队车牌
    if (doubleRowArmyLP)
        TH_SetEnabledPlateFormat(PARAM_TWOROWARMY_ON, &plateConfigTh);

    // 使馆车牌
    if (embassyLP)
        TH_SetEnabledPlateFormat(PARAM_EMBASSY_ON, &plateConfigTh);

    // 农用车车牌
    if (tractorLP)
        TH_SetEnabledPlateFormat(PARAM_TRACTOR_ON, &plateConfigTh);

    // 民航车牌
    if (airportLP)
        TH_SetEnabledPlateFormat(PARAM_MINHANG_ON, &plateConfigTh);

    if (region)
    {
        this->enableRegion = true;
        ::region.left = region->left;
        ::region.right = region->right;
        ::region.top = region->top;
        ::region.bottom = region->bottom;
    }

    return ret;

error:
    error = true;
    return ret;
}

std::string ANPRTH::DetectLPNumber(IplImage* image)
{
    if (error) return "";

    std::string plateNumber;
    TH_PlateIDResult result[6];
    memset(result, 0, sizeof(result));

    int resultNum = 6;

    TH_RECT *region = 0;
    if (enableRegion)
        region = &::region;

#ifdef _WIN32
    WaitForSingleObject(mutex, INFINITE);
#endif
    TH_RecogImage((const unsigned char*)image->imageData, image->width, image->height, result, &resultNum, region, &plateConfigTh);
#ifdef _WIN32
    ReleaseMutex(mutex);
#endif

    return result[0].license;
}
